<script setup>
import {onMounted, provide, reactive, ref} from 'vue'
import Tab from "./Tab.vue";
import PinList from "./PinList.vue";
import useNatureSizeStore from "@/store/natureSize.js";
import usePatternStore from "@/store/pattern";
import useLocationStore from "@/store/location.js";
import useAdminStore from "@/store/admin.js";
import useUUIDUtil from '@/utils/uuid.js'
import defaultImg from '@/assets/map04.jpg'

const imgRef = ref(defaultImg)

const useAdmin = useAdminStore()
//初始化管理员
const useUUID = useUUIDUtil()
const usePattern = usePatternStore()
const useLocation = useLocationStore()
const useNatureSize = useNatureSizeStore()

const rate = ref(1)
// 定义图片相对（0，0）点的坐标的偏移量
const mx = ref(0)
const my = ref(0)
// 定义坐标相对图片真实尺寸的坐标
const rx = ref(0)
const ry = ref(0)
// 图片大小相对真实图片大小的比值
const truthForRate = ref(0)
// 定义鼠标的坐标信息
const clientX = ref(0)
const clientY = ref(0)
const angle = ref(0)
const imgSizeObj = reactive({
  width: 0,
  height: 0
})
// 从缓存中取出，这时需要乘以比值

const pinNodes = ref([])
window.onmousemove = function (e) {
  // 计算鼠标移动的距离
  clientX.value = e.clientX
  clientY.value = e.clientY
  angle.value = Math.atan2(e.clientY, e.clientX) * 180 / Math.PI
}
// 页面加载
onMounted(async () => {
  await getNetworkBgImg()
  await init()
})
const getNetworkBgImg = async () => {
  const {path} = await useAdmin.loadBgImg()
  imgRef.value = path
}
const init = async function () {
  document.addEventListener('drop', function (e) {
    e.preventDefault()
  }, false)
  document.addEventListener('dragover', function (e) {
    e.preventDefault()
  }, false)
  let img = document.querySelector("#img")
  // 屏幕大小
  await Promise.all([new Promise((resolve, reject) => {
    img.onload = async () => {
      img.style.cursor = "grab"
      truthForRate.value = img.naturalWidth / document.documentElement.clientWidth

      if (useNatureSize.getRate() === "null") {
        useNatureSize.setRate(truthForRate.value)
      }
      let relativeRate = truthForRate.value / useNatureSize.getRate()

      let currentPinNodes = await useLocation.getPositions()
      pinNodes.value = currentPinNodes.map(item => {
        return {
          id: item.id,
          uuid: item.uuid,
          icon: item.icon,
          x: item.x / relativeRate,
          y: item.y / relativeRate,
          txt: item.txt,
          link: item.link
        }
      })
      useNatureSize.setNatureSize(img.naturalWidth, img.naturalHeight)
      // 获取整个屏幕的宽度
      let screenWidth = document.documentElement.clientWidth
      img.setAttribute("width", screenWidth)
      img.setAttribute("draggable", true)
      imgSizeObj.width = img.width
      imgSizeObj.height = img.height
      // 监听鼠标滚轮事件
      // 1、根据当前鼠标的坐标为基准进行的缩放，放大应该围绕着当前鼠标的坐标点的位置进行放大
      window.onwheel = function (e) {
        const SCALE_NUM = 1
        // 如果当前坐标没有在图片上，则不进行放大缩小
        if (e.clientX < img.offsetLeft || e.clientX > img.offsetLeft + img.width || e.clientY < img.offsetTop || e.clientY > img.offsetTop + img.height) {
          return
        }
        // 1、控制放大或者缩小
        let imgWidth = img.width
        let imgHeight = img.height
        let imgRate = imgHeight / imgWidth
        let newImgHeight = imgHeight - e.deltaY * SCALE_NUM;
        let newImgWidth = newImgHeight / imgRate
        rate.value = newImgHeight / imgSizeObj.height
        if (rate.value <= 0.5) {
          rate.value = 0.5
          // 反向赋值
          newImgHeight = imgSizeObj.height * 0.5
          newImgWidth = imgSizeObj.width * 0.5
        }
        img.setAttribute("width", newImgWidth + "px")
        img.setAttribute("height", newImgHeight + "px")

        //   移动：1）图片的移动始终保持angle的值不发生改变
        //   2）图片的移动始终保持鼠标的位置不发生改变
        let newLeft = img.offsetLeft - (e.clientX - img.offsetLeft) * (newImgWidth / imgWidth - 1)
        let newTop = img.offsetTop - (e.clientY - img.offsetTop) * (newImgHeight / imgHeight - 1)
        img.style.left = newLeft + "px"
        img.style.top = newTop + "px"
        // console.log("haha", img.offsetLeft, img.offsetTop)
        mx.value = img.offsetLeft
        my.value = img.offsetTop
        // 从新设置图片尺寸
        img.style.transition = "0s"
      }
      // 监听拖拽事件,实现图片跟随鼠标移动，鼠标移动的距离为图片移动的距离
      let imgPos = {
        x: 0,
        y: 0
      }
      // 监听鼠标移动时修改鼠标样式为抓取样式
      img.onmousedown = function (e) {
        img.style.cursor = "grab"
      }
      img.onmouseup = function (e) {
        img.style.cursor = "grab"
      }

      // 1.鼠标按下时，记录鼠标的坐标
      img.ondragstart = function (e) {
        console.log("start")
        img.style.cursor = "grab"

        imgPos.x = e.clientX
        imgPos.y = e.clientY

      }

      // 2.鼠标移动时，计算鼠标移动的距离，从新设置图片的位置
      img.ondragover = function (e) {
        img.style.cursor = "grab"
        e.dataTransfer.dropEffect = "move"
        let newLeft = img.offsetLeft + e.clientX - imgPos.x
        let newTop = img.offsetTop + e.clientY - imgPos.y
        mx.value = img.offsetLeft
        my.value = img.offsetTop

        img.style.left = newLeft + "px"
        img.style.top = newTop + "px"
        imgPos.x = e.clientX
        imgPos.y = e.clientY
      }
//  3.拖拽结束时
      img.ondragend = function (e) {
        //当前图片的坐标
        img.style.cursor = "grab"
      }
      resolve()
    }
  })])

}


const resetSize = () => {
  window.location.reload()
}

const eventContainerClick = (e) => {
  if (usePattern.modal !== "edit") {
    return
  }
//   当前坐标为视口坐标，减去图片的偏移量，再除以放大倍数，就是当前图片上的坐标
//   需要拿到相对图片的坐标点
  let img = document.querySelector("#img")
  // rate表示图片的放大缩小倍数
  //truthForRate相对真实图片的坐标
  let x = (e.clientX - img.offsetLeft) / rate.value * truthForRate.value
  let y = (e.clientY - img.offsetTop) / rate.value * truthForRate.value
  const data = {uuid: useUUID.getUUID(), x, y, txt: "", icon: '', link: '', newPin: true}
  pinNodes.value.push(data)
  // 手动滚动一小段距离onwheelLen
  let onwheelLen = 1
//   执行一次滚动事件
  setTimeout(() => {
    let e1 = new WheelEvent("wheel", {deltaY: onwheelLen})
    window.dispatchEvent(e1)
  }, 10)
  //   执行一次滚动事件
  setTimeout(() => {
    let e2 = new WheelEvent("wheel", {deltaY: -onwheelLen})
    window.dispatchEvent(e2)
  }, 10)
}

// 监听浏览器尺寸的变化
window.onresize = () => {
  return (() => {
    //   从新刷新页面
    window.location.reload()
    useNatureSize.setRate("null")
  })()
}
const showTab = ref(useAdmin.getAuth())

// 定义一个方法，用于删除pin节点
const delPin = (obj) => {
  console.log("父级delPin", obj.uuid)
  let index = pinNodes.value.findIndex(item => {
    return item.uuid === obj.uuid
  })
  pinNodes.value.splice(index, 1)
}
provide("delPin", delPin)
const changeBgImg = async () => {
  const {path} = await useAdmin.loadBgImg()
  imgRef.value = path
}
</script>

<template>
  <div class="p-container" id="p-container">
    <img @click="eventContainerClick" id="img" style="overflow: hidden;position: absolute;" :src="imgRef"
         alt="">
    <div v-if="showTab==1">
      <Tab :rate="rate" :pinNodes="pinNodes" @init="init" @changeBgImg="changeBgImg" :x="clientX" :y="clientY"
           :angle="angle" :mx="mx" :my="my"
           :truthForRate="truthForRate"
           @resetSize="resetSize"></Tab>
    </div>
    <component :is="PinList" :rate="rate" :nodes="pinNodes" :mx="mx" :my="my"/>
  </div>

</template>

<style scoped>
.p-container {
  position: relative;
  width: 100vw;
  height: 100vh;
  overflow: hidden;
  background: #ddd;
  box-sizing: border-box;
  z-index: 0;

  .card {
    position: absolute;
  }
}
</style>